package com.lollipop.synthential.ip;

import lombok.extern.slf4j.Slf4j;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author: J.K
 * @Date: 2022-06-09 10:45
 * @Description: 根据IP地址获取地域信息
 */
@Slf4j
public class IPAddressUtil {


    public static void main(String[] args) {
        // 测试ip 114.251.62.226 北京市
        // 221.235.44.19 湖北省=武汉市
        // 153.19.50.62 波兰
        // 169.235.24.133 美国
        String ip = "218.93.176.206";
        Map<String, String> map = getIPAddress(ip);
        log.info("所在区域：{}", map);
    }

    /**
     * 先去查询 百度IP库，如果返回失败或ip为国外，则去查询新浪IP库
     *
     * @param ip
     * @return
     */
    public static Map<String, String> getIPAddress(String ip) {
        try {
            log.info("调用百度IP库……");
            Map<String, String> map = getBaiDuIPAddress(ip);
            if (map.get("ip") != null) {
                return map;
            }
            log.info("调用新浪IP库……");
            Map<String, String> map2 = getSinaIPAddress(ip);
            if (map2.get("ip") != null) {
                return map2;
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("根据IP地址获取地域信息失败", e);
        }
        return null;
    }

    /**
     * 解析 百度IP库返回结果
     * http://lbsyun.baidu.com/index.php?title=webapi/ip-api
     *
     * @param ip
     * @return
     */
    private static Map<String, String> getBaiDuIPAddress(String ip) {
        //存放 返回结果
        Map<String, String> map = new HashMap<>();
        String ak = "A0kaOOGj3wECjLS1LSD7AyGP5GXumFIt";
        String url = "http://api.map.baidu.com/location/ip?ak=" + ak + "&coor=bd09ll&ip=" + ip;
        String json = getResult(url, "UTF-8");
        log.info("百度IP库返回结果:{}" + json);
        if (json == null) {
            return map;
        }
        Map<String, Object> objectMap = (Map<String, Object>) JacksonUtils.jsonToObject(json, Map.class);
        // 返回正常
        if ("0".equals(String.valueOf(objectMap.get("status"))) && objectMap.get("content") != null) {
            Map<String, String> subMap = (Map<String, String>) objectMap.get("content");
            String address = subMap.get("address");
            map.put("ip", ip);
            String country = String.valueOf(objectMap.get("address"));
            // 中国
            if (country != null && !"".equals(country) && country.indexOf("CN") == 0) {
                map.put("address", "中国" + address);
            } else {
                map.put("address", address);
            }
        } else {
            // 1:服务器内部错误--该服务响应超时或系统内部错误  排除掉不支持的ip（国外、局域网等）
            if (!"1".equals(String.valueOf(objectMap.get("status")))) {
                log.error("调用百度IP库出现异常，异常信息：", objectMap.get("message"));
            }
        }
        return map;
    }

    /**
     * 解析 新浪IP库返回结果
     *
     * @param ip
     * @return
     */
    private static Map<String, String> getSinaIPAddress(String ip) {
        // 存放返回结果
        Map<String, String> map = new HashMap<String, String>();
        String url = "http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=json&ip=" + ip;
        String json = getResult(url, "UTF-8");
        log.info("新浪IP库返回结果:" + json);
        if (json == null) {
            return map;
        }
        // 返回正常
        if (json.length() > 2) {
            Map<String, String> objectMap = (Map<String, String>) JacksonUtils.jsonToObject(json, Map.class);
            if (objectMap != null) {
                String country = objectMap.get("country");
                String province = objectMap.get("province");
                String city = objectMap.get("city");
                map.put("ip", ip);
                if (province == null || "".equals(province) || city == null || "".equals(city)) {
                    map.put("address", country);
                } else {
                    map.put("address", country + province + "省" + city + "市");
                }
            }
        } else {
            log.error("调用新浪IP库出现异常", ip);
        }
        return map;
    }

    /**
     * 请求urlStr，返回结果
     *
     * @param urlStr
     * @param encoding
     * @return
     */
    private static String getResult(String urlStr, String encoding) {
        URL url = null;
        HttpURLConnection connection = null;
        try {
            url = new URL(urlStr);
            // 新建连接实例
            connection = (HttpURLConnection) url.openConnection();
            // 设置连接超时时间，单位毫秒
            //connection.setConnectTimeout(2000);
            // 设置读取数据超时时间，单位毫秒
            //connection.setReadTimeout(2000);
            // 是否打开输出流 true|false
            //connection.setDoOutput(true);
            // 是否打开输入流true|false
            //connection.setDoInput(true);

            // 提交方法POST|GET
            connection.setRequestMethod("GET");
            // 是否缓存true|false
            connection.setUseCaches(false);
            // 打开连接端口
            connection.connect();
            // 往对端写完数据对端服务器返回数据
            BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), encoding));
            // 以BufferedReader流来读取
            StringBuffer buffer = new StringBuffer();
            String line = "";
            while ((line = reader.readLine()) != null) {
                buffer.append(line);
            }
            reader.close();
            return buffer.toString();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (connection != null) {
                // 关闭连接
                connection.disconnect();
            }
        }
        return null;
    }

}
